﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

/// <summary>
/// 这个类会造成性能下降，应该动态启用和关闭。
/// CusSkinMeshRdr也是不需要每帧（静止帧）都更新法线和位置
/// TODO：
/// （暂缓）投射时轨迹匹配复合曲线，曲线拟合有点没学会。先需要学微积分偏导数。
/// （暂缓）修复平坦子层级后的骨骼绘制
/// （完成）通过使用Slope值，使投射时头发的“上向”（现在是Forward）朝向摄像机。
/// （完成）分段曲线（复合贝塞尔曲线）
/// （完成）支持自带的SMR，对比性能
/// （完成）随时调整头发模型，将调整类改为工具类
/// （完成）Gizmos操纵杆（移动部分）
/// Gizmos操纵球
/// （完成）曲线顶点绘制
/// </summary>
[Serializable]
public partial class CurveData
{
    public void SnapBonesToCurve()
    {
        if (bones == null) return;
        if (curve == null || curve.Count == 0) return;
        if (bones.Length < 2) return;
        bones[0].position = curve[0].vector;

        curve.InitRangeTimes();

        Vector3 targetPos;
        float t = 0f;

        var root = bones[0];
        root.rotation = Quaternion.identity;
        Quaternion Q;
        Q = Quaternion.AngleAxis(-90, Vector3.right);
        root.rotation = Q * root.rotation;
        Q = Quaternion.AngleAxis(circleAngle, Vector3.up);
        root.rotation = Q * root.rotation;
        if (!HairGen.I.snap) return;
        for (int i = 0; i < bones.Length; i++)
        {
            var bone = bones[i];
            if (i > 0)
            {
                bone.localRotation = Quaternion.identity;
                var parent = bones[i - 1];
                bone.position = parent.position + parent.up * bonesLength[i - 1];
            }
            while (true)
            {
                t += step;
                targetPos = curve.Evaluate(t); // 步进曲线，直到贴合
                var dist = Vector3.Distance(bones[i].position, targetPos);
                if (dist > bonesLength[i]) break;
                if (t > 1f) goto syncPair;
            }
            var to = targetPos - bone.position;
            //Debug.DrawRay(bone.position, bone.right * 0.1f, Color.red);
            Snap3(bone, to);
            Snap1(bone, to);
            //SnapA(bone, to, Vector3.up);
            /// twist
            var q = Quaternion.AngleAxis(curve.Slope(t), bone.up);
            bone.rotation = q * bone.rotation;
        }
        syncPair:
        SyncPair();
    }
    void SyncPair()
    {
        if (Selector.current == mono.transform)
        {
            string pairName = "";
            if (mono.name.EndWithIC(".r")) pairName = mono.name.ReplaceEnd(".r", ".l");
            if (mono.name.EndWithIC(".l")) pairName = mono.name.ReplaceEnd(".l", ".r");
            var pairT = mono.transform.parent.Search(pairName);
            if (pairT != null)
            {
                pair = pairT.GetComponent<Hair>();
                pair.curveData.pair = mono.GetComponent<Hair>();
                pair.curveData.circleAngle = 360 - circleAngle;

                var k = curve.GetEnumerator();
                foreach (var kM in pair.curveData.curve)
                {
                    k.MoveNext();
                    var c = k.Current;
                    kM.vector = c.vector.MirrorX();
                    kM.inTangent = c.inTangent.MirrorX();
                    kM.outTangent = c.outTangent.MirrorX();
                    kM.slope = -c.slope;
                }
            }
        }
    }
}
